using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Newtonsoft.Json.Linq;
using UnityEngine;
using UnityEngine.Networking;
using HyxFrame.Core;

public class TextFileReader 
{
    /// <summary>
    /// 配置项字典，用于存储所有的配置键值对
    /// Key: 配置项名称
    /// Value: 配置项值
    /// </summary>
    private static Dictionary<string, string> m_dicAttibute = new Dictionary<string, string>();

    /// <summary>
    /// 从Resources文件夹读取文本文件
    /// </summary>
    /// <param name="filePath">Resources文件夹下的相对路径，不包含扩展名</param>
    /// <returns>文件内容字符串</returns>
    public static string ReadFromResources(string filePath)
    {
        TextAsset textAsset = Resources.Load<TextAsset>(filePath);
        if (textAsset != null)
        {
            return textAsset.text;
        }
        else
        {
            Debug.LogError("无法从Resources加载文件: " + filePath);
            return null;
        }
    }

    /// <summary>
    /// 从持久化数据路径读取文本文件
    /// </summary>
    /// <param name="fileName">文件名，包含扩展名</param>
    /// <returns>文件内容字符串</returns>
    public static string ReadFromPersistentDataPath(string fileName)
    {
        string filePath = Path.Combine(Application.persistentDataPath, fileName);
        
        if (File.Exists(filePath))
        {
            try
            {
                return File.ReadAllText(filePath);
            }
            catch (System.Exception e)
            {
                Debug.LogError("读取文件时出错: " + e.Message);
                return null;
            }
        }
        else
        {
            Debug.LogError("文件不存在: " + filePath);
            return null;
        }
    }

    /// <summary>
    /// 从绝对路径读取文本文件
    /// </summary>
    /// <param name="absolutePath">文件的完整路径</param>
    /// <returns>文件内容字符串</returns>
    public static string ReadFromAbsolutePath(string absolutePath)
    {
        if (File.Exists(absolutePath))
        {
            try
            {
                return File.ReadAllText(absolutePath);
            }
            catch (System.Exception e)
            {
                Debug.LogError("读取文件时出错: " + e.Message);
                return null;
            }
        }
        else
        {
            Debug.LogError("文件不存在: " + absolutePath);
            return null;
        }
    }

    /// <summary>
    /// 从StreamingAssets文件夹读取文本文件
    /// </summary>
    /// <param name="fileName">文件名，包含扩展名</param>
    /// <returns>文件内容字符串</returns>
    public static string ReadFromStreamingAssets(string fileName)
    {
        string filePath = Path.Combine(Application.streamingAssetsPath, fileName);

        // 根据平台选择不同的读取方式
        if (filePath.Contains("://") || filePath.Contains(":///"))
        {
            // Android平台，使用 UnityWebRequest 替换过时的 WWW
            using (UnityWebRequest www = UnityWebRequest.Get(filePath))
            {
                var operation = www.SendWebRequest();
                while (!operation.isDone) { }

                if (www.result != UnityWebRequest.Result.Success)
                {
                    Debug.LogError("读取文件时出错: " + www.error);
                    return null;
                }
                return www.downloadHandler.text;
            }
        }
        else
        {
            // 其他平台
            if (File.Exists(filePath))
            {
                try
                {
                    return File.ReadAllText(filePath);
                }
                catch (System.Exception e)
                {
                    Debug.LogError("读取文件时出错: " + e.Message);
                    return null;
                }
            }
            else
            {
                Debug.LogError("文件不存在: " + filePath);
                return null;
            }
        }
    }

    /// <summary>
    /// 异步从StreamingAssets文件夹读取文本文件
    /// </summary>
    /// <param name="fileName">文件名，包含扩展名</param>
    /// <param name="callback">读取完成后的回调</param>
    public static void ReadFromStreamingAssetsAsync(string fileName, System.Action<string> callback)
    {
        string filePath = Path.Combine(Application.streamingAssetsPath, fileName);
        
        if (filePath.Contains("://") || filePath.Contains(":///"))
        {
            // Android平台
            MonoBehaviourHelper.Instance.StartCoroutine(ReadFileAsync(filePath, callback));
        }
        else
        {
            // 其他平台
            if (File.Exists(filePath))
            {
                try
                {
                    string content = File.ReadAllText(filePath);
                    callback?.Invoke(content);
                }
                catch (System.Exception e)
                {
                    Debug.LogError("读取文件时出错: " + e.Message);
                    callback?.Invoke(null);
                }
            }
            else
            {
                Debug.LogError("文件不存在: " + filePath);
                callback?.Invoke(null);
            }
        }
    }

    private static System.Collections.IEnumerator ReadFileAsync(string filePath, System.Action<string> callback)
    {
        UnityWebRequest www = UnityWebRequest.Get(filePath);
        yield return www.SendWebRequest();
        
        if (www.result != UnityWebRequest.Result.Success)
        {
            Debug.LogError("读取文件时出错: " + www.error);
            callback?.Invoke(null);
        }
        else
        {
            callback?.Invoke(www.downloadHandler.text);
        }
    }

    /// <summary>
    /// 读取本地数据基础表信息
    /// </summary>
    /// <param name="fileName">文件名</param>
    /// <returns>协程</returns>
    public static IEnumerator LoadLocalFiles(string fileName)
    {
        // 打开本地配置文件
        string pathLocalConfig = Application.streamingAssetsPath;
        Debug.LogFormat("load app config: {0}", pathLocalConfig);

        yield return null;

        UnityWebRequest www = UnityWebRequest.Get(Path.Combine(pathLocalConfig, fileName));
        yield return www.SendWebRequest();

        if (www.result != UnityWebRequest.Result.Success)
        {
            Debug.LogError("load pathLocalConfig : error - " + www.error);
            yield break;
        }
        
        string data = www.downloadHandler.text;

        // 读取并保存文件
        if (!LoadClientConfigLocal(data))
        {
            Debug.LogError("LoadClientConfigLocal : error");
            yield break;
        }

        yield return null;
    }

    /// <summary>
    /// 解析JSON格式的配置文本并保存到字典中
    /// </summary>
    /// <param name="text">JSON格式的配置文本</param>
    /// <returns>解析成功返回true，失败返回false</returns>
    public static bool LoadClientConfigLocal(string text)
    {
        // 检查输入文本是否为空
        if (string.IsNullOrEmpty(text))
        {
            Debug.LogError("配置文本为空");
            return false;
        }

        try
        {
            // 解析JSON文本
            JObject json = JObject.Parse(text);

            // 清空现有配置，避免重复
            m_dicAttibute.Clear();

            // 遍历JSON对象，将所有配置项添加到字典中
            foreach (var item in json)
            {
                // 检查是否已存在相同的键
                if (!m_dicAttibute.ContainsKey(item.Key))
                {
                    m_dicAttibute.Add(item.Key, item.Value.ToString());
                    Debug.Log($"配置项加载: {item.Key} = {item.Value}");
                }
                else
                {
                    Debug.LogWarning($"配置项重复: {item.Key}");
                }
            }
            return true;
        }
        catch (Exception ex)
        {
            // 捕获并记录JSON解析过程中的异常
            Debug.LogError($"解析JSON配置失败: {ex.Message}");
            return false;
        }
    }

    /// <summary>
    /// 获取指定配置项的值
    /// </summary>
    /// <param name="key">配置项的键</param>
    /// <returns>配置项的值，如果不存在则返回空字符串</returns>
    public static string GetAttibute(string key)
    {
        // 检查键是否为空
        if (string.IsNullOrEmpty(key))
        {
            Debug.LogWarning("配置项键为空");
            return string.Empty;
        }

        // 尝试从字典中获取值
        if (m_dicAttibute.TryGetValue(key, out string result))
        {
            return result;
        }

        Debug.LogWarning($"未找到配置项: {key}");
        return string.Empty;
    }

    /// <summary>
    /// 获取指定配置项的布尔值
    /// </summary>
    /// <param name="key">配置项的键</param>
    /// <param name="defaultValue">默认值，当配置项不存在或转换失败时返回此值</param>
    /// <returns>配置项的布尔值</returns>
    public static bool GetAttibuteBool(string key, bool defaultValue = false)
    {
        // 获取配置项的字符串值
        string result = GetAttibute(key);
        // 将字符串转换为布尔值
        return BoolConvert(result, defaultValue);
    }

    /// <summary>
    /// 将字符串转换为布尔值
    /// </summary>
    /// <param name="value">要转换的字符串</param>
    /// <param name="defaultValue">默认值，当转换失败时返回此值</param>
    /// <returns>转换后的布尔值</returns>
    private static bool BoolConvert(string value, bool defaultValue = false)
    {
        // 检查字符串是否为空
        if (string.IsNullOrEmpty(value))
            return defaultValue;

        // 尝试直接解析布尔值
        if (bool.TryParse(value, out bool result))
            return result;

        // 检查是否为"1"
        if (value.Equals("1"))
            return true;

        // 检查是否为"0"
        if (value.Equals("0"))
            return false;

        // 检查是否为"true"（不区分大小写）
        if (value.ToLower().Equals("true"))
            return true;

        // 检查是否为"false"（不区分大小写）
        if (value.ToLower().Equals("false"))
            return false;

        // 所有转换都失败时返回默认值
        return defaultValue;
    }
}

